import { IKeyVo } from "./KeyVoUtil";
import { IEnum, ITags } from "./ClsFactory";
import { typeParserMgr } from "../mgr/TypeParserMgr";

export class ValueUtil {

    static parserValue(value: string, keyVo: IKeyVo) {
        var result: any;
        var type = keyVo.type || "";
        switch (type.toLowerCase()) {
            case "number":
            case "float":
                result = this.toNum(value);
                break;
            case "int":
                result = this.toInt(value);
                break;
            case "array<string>":
            case "string[]":
                result = this.toArray(value, "string");
                break;
            case "array<number>":
            case "number[]":
            case "float[]":
                result = this.toArray(value, "number");
                break;
            case "int[]":
                result = this.toArray(value, "int");
                break;
            case "array<enum>":
            case "enum[]":
                result = this.toEnumArray(value, keyVo.enum);
                break;
            case "enum":
                result = this.toEnum(value, keyVo.enum);
                break;
            case "json":
                if (value === undefined) return value;
                result = this.toJson(value);
                break;
            case "tags":
                result = this.toTags(value, keyVo.tags);
                break;
            case "enumkey":
                result = value;
                break;
            case "boolean":
            case "bool":
                result = this.toBoolean(value);
                break;
            default:
                let parser = typeParserMgr.getParser(type);
                if (parser != null) return parser.parseValue(value);
                if (value === undefined) return value;
                result = value.toString();
                break;
        }
        return result;
    }


    static toNum(str: string): number {
        var num = parseFloat(str);
        if (isNaN(num)) return 0;
        return num;
    }
    static toInt(str: string): number {
        var num = parseInt(str);
        if (isNaN(num)) return 0;
        return num;
    }

    static toEnumArray(value: string, enumVo: IEnum): any[] {
        let result: any[] = [];
        if (value == null || value === "") { return result; }
        let temp: string[];
        if (value.indexOf('|') >= 0) {
            temp = value.split('|');
        } else {
            temp = value.toString().replace(/\r\n/g, "\n").split("\n");
        }
        for (const cell of temp) {
            result.push(this.toEnum(cell, enumVo));
        }
        return result;
    }

    static toArray(value: string, child: "string" | "number" | "int" | "float"): Array<number | string> {
        var result: Array<number | string>;
        if (value == null || value === undefined || value === "") return [];

        result = value.toString().replace(/\r\n/g, "\n").replace(/,/g, "\n").split("\n");
        for (var i = 0; i < result.length; i++) {
            if (result[i] === "") {
                result.splice(i, 1);
                i--;
                continue;
            }
            if (child == "number" || child == "float") {
                result[i] = this.toNum(<string>result[i]);
            } else if (child == "int") {
                result[i] = this.toInt(<string>result[i]);
            }
        }
        return result;
    }

    static toEnum(value: string, enumVo: IEnum) {
        return enumVo.getValue(value);
    }

    static toJson(value: string): any {
        if (!value) return null;
        return JSON.parse(value);
    }

    static toTags(value: string, tags: ITags): number {
        if (!value) return 0;
        var arr = value.split("|");
        var num = 0;
        for (var i = 0; i < arr.length; i++) {
            num += tags.getValue(arr[i]);
        }
        return num;
    }

    static toBoolean(value: string): boolean {
        if (typeof value == "boolean") return value;
        if (!value || value.toLocaleLowerCase() == "false") return false;
        return true;
    }
}